Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add methods to create ArrayBuffers from byte arrays #30445

Closed
wants to merge 2 commits into from
Closed

Add methods to create ArrayBuffers from byte arrays #30445

wants to merge 2 commits into from

Conversation

savv
Copy link

@savv savv commented Nov 20, 2020

Summary

This PR adds a factory method to the ArrayBuffer class, so that JSI methods can return them as results.

Changelog

[General] [Added] - Factory method for ArrayBuffer in the JavaScriptCore implementation of JSI

Test Plan

I have a test app where I can directly return data from LevelDB and see ArrayBuffers on the JS side! Let me know if I should add a test case to rn-tester.


This change is Reviewable

@facebook-github-bot
Copy link
Contributor

Hi @savv!

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file.

In order for us to review and merge your code, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@savv savv changed the title Add methods to create ArrayBuffers from byte buffers Add methods to create ArrayBuffers from byte arrays Nov 20, 2020
@react-native-bot react-native-bot added the Type: Enhancement A new feature or enhancement of an existing feature. label Nov 20, 2020
@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: a023ff0

@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,519,904 +330
android hermes armeabi-v7a 7,104,976 +158
android hermes x86 7,960,210 +173
android hermes x86_64 7,871,609 +271
android jsc arm64-v8a 8,989,994 +326
android jsc armeabi-v7a 8,558,189 +174
android jsc x86 8,991,807 +171
android jsc x86_64 9,543,470 +284

Base commit: a023ff0

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 20, 2020
@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

@savv
Copy link
Author

savv commented Nov 21, 2020

FYI - this PR is quite similar to #28961 from @ryantrem

I'm CCing the same people here in hopes of getting it merged in! :-)
@mhorowitz, @tmikov @bghgary @ @shergin

@tmikov
Copy link

tmikov commented Nov 21, 2020

You are adding new method to the base JSI interface but only implementing it for JSC. It seems like If we merge it, it will break the Hermes JSI implementation.

@@ -252,6 +252,7 @@ class JSI_EXPORT Runtime {

virtual String createStringFromAscii(const char* str, size_t length) = 0;
virtual String createStringFromUtf8(const uint8_t* utf8, size_t length) = 0;
virtual Object createArrayBufferFromBytes(const void* bytes, size_t length) = 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this declaration probably shouldn't be in the middle of the string-related methods.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it a bit further below. Does that work?

@ryantrem
Copy link
Contributor

I believe everything under ReactCommon/jsi/jsi is automatically merged from https://github.com/facebook/hermes/tree/master/API/jsi/jsi, so I think you need to make API changes there first and wait for them to be migrated to the react-native repo before adding a JSC specific implementation of createArrayBufferFromBytes.

@@ -252,6 +252,7 @@ class JSI_EXPORT Runtime {

virtual String createStringFromAscii(const char* str, size_t length) = 0;
virtual String createStringFromUtf8(const uint8_t* utf8, size_t length) = 0;
virtual Object createArrayBufferFromBytes(const void* bytes, size_t length) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @tmikov mentioned, there are multiple implementations of JSI for different JS engines. In addition to JSC and Hermes, there is also V8, Chakra, and a new ABI safe JSI wrapper for Windows. Maybe we could provide a default (non-functional) implementation, and allow JS engine specific implementations to opt-in over time?

virtual Object createArrayBufferFromBytes(const void* bytes, size_t length) { throw std::runtime_error{"Not implemented."}; }

I don't think there is anything like this in JSI already though, so not sure what the right pattern is for expanding API surface area.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Ryan, I went ahead and added this. There seems to be precedent for this, which makes me think it's a good suggestion:

throw std::runtime_error("Unsupported");

I also implemented the same functionality in hermes:
facebook/hermes#419

@ryantrem
Copy link
Contributor

This PR adds a factory method to the ArrayBuffer class, so that JSI methods can return them as results.

It would be great to see this change make it in. This would be really helpful when dealing with large blocks of data managed by native code but accessible by JavaScript. We would definitely use it in BabylonReactNative.

@savv
Copy link
Author

savv commented Dec 22, 2020

As per the discussion on facebook/hermes#419 this can be done by getting the ArrayBuffer constructor: https://gist.github.com/mhorowitz/4915d43b8d82ae0eb98a157e689ba23e

So I'm closing this PR.

@mrousavy
Copy link
Contributor

@savv this does still copy the "byte array". In my case I receive a buffer (void *) from an API and I would like to create an ArrayBuffer from that given void * buffer, that is currently not possible using JSI and your PR would solve this (afaik) - so why close it?

@savv
Copy link
Author

savv commented Aug 6, 2021

Capturing our discussion for posterity:
The implementation in this PR was still copying bytes around. You’d have to change Hermes in a few places to use std::move instead of copying strings, may be difficult (I don't understand Hermes's memory ownership model enough to comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Type: Enhancement A new feature or enhancement of an existing feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants